﻿function AzureOnlineViewModel(context) {

    var spaRuntime = context.spaRuntime;

    var screen = ko.observable('');

    var tablesRoute = new SpaRoute('tables', 'tables').addExecute(function (ev, args, phash) {
        screen('tables');
    });

    var tableDetailsRoute = new SpaRoute('tableRecords', 'tables/{tableName}').addExecute(function (ev, args, phash) {
        screen('tables');
        context.tables.table(args.tableName);
    });

    var blobsRoute = new SpaRoute('blobs', 'blobs').addExecute(function (ev, args, phash) {
        screen('blobs');
    });

    var blobDetailsRoute = new SpaRoute('blobContainerDetails', 'blobs/{blobName}').addExecute(function (ev, args, phash) {
        screen('blobs');
        context.blobs.container(args.blobName);
    });

    var pageBlobViewerRoute = new SpaRoute('pageBlobViewer', 'blobs/{containerName}/{blobName}/pageBlobViewer').addExecute(function (ev, args, phash) {
        screen('blobs');
        context.blobs.container(args.containerName);
    });

    var queuesRoute = new SpaRoute('queues', 'queues').addExecute(function (ev, args, phash) {
        screen('queues');
    });

    var queueDetailsRoute = new SpaRoute('queueMessages', 'queues/{queueName}').addExecute(function (ev, args, phash) {
        screen('queues');
        context.queues.queue(args.queueName);
    });

    var consoleRoute = new SpaRoute('console', 'console').addExecute(function () {
        screen('console');
    });

    var accountsRoute = new SpaRoute('accounts', 'accounts').addExecute(function () {
        screen('accounts');
    });

    var consoleCreateRoute = new SpaRoute('consoleCreateRequest', 'console/new').addExecute(function () {
        screen('console');
    });

    var consoleRequestDetailsRoute = new SpaRoute('consoleRequestDetails', 'console/{requestId}').addExecute(function () {
        screen('console');
    });

    var docsRoute = new SpaRoute('docs', 'docs').addExecute(function (ev, args, phash) {
        screen('docs');
    });

    var mainRoute = new SpaRoute('main', '').addExecute(function (ev, args, phash) {
        screen('main');
    });

    spaRuntime.addRoutes(tablesRoute, blobsRoute, queuesRoute, consoleRoute, consoleCreateRoute, consoleRequestDetailsRoute, mainRoute, tableDetailsRoute,
        blobDetailsRoute, pageBlobViewerRoute,
        queueDetailsRoute, accountsRoute, docsRoute);

    var termsOfUse = new AzureOnlineTermsOfUse(context);
    
    this.tablesView = new AzureOnlineTablesView(context);
    this.blobsView = new AzureOnlineBlobsView(context);
    this.queuesView = new AzureOnlineQueuesView(context);
    this.consoleView = new AzureOnlineConsoleViewModel(context);
    this.accountsView = new AzureOnlineAccountsViewModel(context);
    this.servicePropertiesView = new AzureOnlineServicePropertiesView(context);
    this.screen = screen;

    this.tablesUrl = ko.computed(function () { return tablesRoute.formatHash({}); });
    this.blobsUrl = ko.computed(function () { return blobsRoute.formatHash({}); });
    this.queuesUrl = ko.computed(function () { return queuesRoute.formatHash({}); });
    this.consoleUrl = ko.computed(function () { return consoleRoute.formatHash({}); });
    this.accountsUrl = ko.computed(function () { return accountsRoute.formatHash({}); });
    this.docsUrl = ko.computed(function () { return docsRoute.formatHash({}); });
    this.termsOfUse = termsOfUse;
    
    this.context = context;
}

function AzureOnlineDataContext() {

    var self = this;
    
    var spaRuntime = new SpaRuntime();

    var accounts = {
        accounts: ko.observableArray([]),
        account: ko.observable(null),
        findByName: function (name) {
            var accs = accounts.accounts();
            for (var i = 0; i < accs.length; i++) {
                var acc = accs[i];
                if (acc.storageName() == name) return acc;
            }
            return null;
        }
    };
    accounts.accountName = ko.computed({
        read: function () {
            var acc = accounts.account();
            if (acc) return acc.storageName();
            return null;
        },
        write: function (val) {
            var accs = accounts.accounts();
            for (var i = 0; i < accs.length; i++) {
                var acc = accs[i];
                if (acc.storageName() == val) {
                    accounts.account(acc);
                }
            }
        }
    });

    var settings = new Settings();
    var generalSettings = settings.folder('general');

    var accountSettings = ko.computed(function () {
        return settings.folder('accounts').folder(accounts.accountName());
    });

    var proxyChannel = new AzureProxyChannel();
    var channel = new AzureOnlineLoggingChannel(proxyChannel);

    var console = {
        requests: channel.requests,
        requestId: ko.observable(null)
    };

    var api = ko.computed(function () {
        var acc = accounts.account();
        if (!acc) return null;
        var name = acc.storageName();
        var key = acc.storageKey();
        var devStorage = acc.devStorage();
        
        if (devStorage || (name && key)) {
            var account = new AzureStorageAccount();
            if (devStorage) {
                account.useDevStorage();
            } else {
                account.setAccountNameAndKey(name, key);
            }
            return new AzureStorageApi(account, channel);
        }
        return null;
    });

    var proxyType = ko.observable('shared');
    proxyType(generalSettings.getItem('proxyType') || 'shared');
    ko.computed(function () {
        var type = proxyType();
        proxyChannel.setProxyType(type);
        generalSettings.setItem('proxyType', type);
    });

    this.spaRuntime = spaRuntime;
    this.channel = channel;
    this.proxyType = proxyType;
    this.api = api;

    this.console = console;
    this.accounts = accounts;
    this.settings = settings;
    this.accountSettings = accountSettings;

    this.setSharedProxyType = function () {
        proxyType('shared');
    };
    this.setLocalProxyType = function () {
        proxyType('local');
    };
    
    var tables = new AzureOnlineTablesDataContext(self);
    var blobs = new AzureOnlineBlobsDataContext(self);
    var queues = new AzureOnlineQueuesDataContext(self);
    self.tables = tables;
    self.blobs = blobs;
    self.queues = queues;
}

function AzureOnlineTermsOfUse(context) {

    var dispatcher = $({});
    
    var accepted = ko.observable(context.settings.folder('termsOfUse').getItem('accepted') === 'true');

    function accept() {
        accepted(true);
        context.settings.folder('termsOfUse').setItem('accepted', 'true');
        dispatcher.trigger('success');
    }
    
    this.addOnSuccess = function (handler) {
        dispatcher.bind('success', handler);
    };
    
    this.accepted = accepted;
    this.accept = accept;
}